﻿using System.IO;
using System.Reflection;
using Autofac;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using RayD.Core;
using Microsoft.AspNetCore.StaticFiles;
using RayD.App.Quartz;
using RayD.App.Setup;
using FluentValidation.AspNetCore;

namespace RayD.WebApi
{
    public class Startup
    {
        public Startup(IConfiguration configuration, IWebHostEnvironment env)
        {
            Configuration = configuration;
            Env = env;
        }
        public IConfiguration Configuration { get; }
        public IWebHostEnvironment Env { get; }


        //运行时将调用此方法。 使用此方法将服务添加到容器。
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton(Configuration);
            services.AddSingleton(new Logger(Directory.GetParent(Env.ContentRootPath).FullName));
            services.AddSingleton(new IOHelper(Directory.GetParent(Env.ContentRootPath).FullName, new FileExtensionContentTypeProvider()));

            services.AddCorsSetup();
            services.AddJwtSetup();
            services.AddMemoryCacheSetup();
            services.AddMiniProfilerSetup();
            services.AddSwaggerSetup();
            services.AddQuartzSetup();

            #region 允许同步
            services.Configure<KestrelServerOptions>(x => x.AllowSynchronousIO = true)
                    .Configure<IISServerOptions>(x => x.AllowSynchronousIO = true);
            #endregion

            #region MVC
            services.AddControllers(o =>
            {
                //处理Get请求数组接受中[]不识别问题
                o.ValueProviderFactories.Add(new JQueryQueryStringValueProviderFactory());
                //注册全局异常捕获过滤器
                o.Filters.Add<ApiExceptionFilter>();

            })
            //.AddControllersAsServices()
            //全局配置Json序列化处理
            .AddNewtonsoftJson(options =>
            {
                //忽略循环引用
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                //不使用驼峰样式的key
                options.SerializerSettings.ContractResolver = new DefaultContractResolver();
                //设置时间格式
                //options.SerializerSettings.DateFormatString = "yyyy-MM-dd";
            })
            //三方验证包
            .AddFluentValidation(fv =>
            {
                //程序集方式引入
                //fv.RegisterValidatorsFromAssemblyContaining<>()
                //去掉其他验证，只使用FluentValidation的验证规则
                fv.RunDefaultMvcValidationAfterFluentValidationExecutes = false;
            });
            #endregion

        }
        // 注意在CreateDefaultBuilder中，添加Autofac服务工厂
        public void ConfigureContainer(ContainerBuilder builder)
        {
            builder.RegisterModule(new AutofacModuleRegister());
        }

        //运行时将调用此方法。 使用此方法来配置HTTP请求管道。使用已注册的服务
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                //生产环境下将Swagger挪入
            }

            // 初始化IM客户端
            IMSetup.InitClient();
            // 请求响应
            app.UseReuestResponseLog();
            // Swagger
            app.UseSwaggerMid(() => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("RayD.WebApi.index.html"));
            // 简单的跨域处理
            app.UseCors("LimitRequests");
            // 使用静态文件
            //app.UseStaticFiles();
            // 返回错误码
            app.UseStatusCodePages();//把错误码返回前台，比如是404
            // Routing
            app.UseRouting();
            // 开启JWT认证
            app.UseAuthentication();
            // 然后是授权中间件
            app.UseAuthorization();
            // 接口性能分析
            if (AppSettings.MiniProfilerAOP.Enabled)
            {
                app.UseMiniProfiler();
            }
            // 短路中间件，配置Controller路由
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }

    }
}
